package com.zs.demo;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * @Author: Zhangshuqing
 * @Description:
 * @Date: Created in 16:38 2018/4/11
 * @Modified By:
 */
public class Server {

    public void startServer() throws IOException {
        ServerSocket serverSocket = null;
        InputStream in = null;
        try
        {
            serverSocket = new ServerSocket(8080);
            int recvMsgSize = 0;
            byte[] recvBuf = new byte[1024];
            while(true){
                Socket clntSocket = serverSocket.accept();
                SocketAddress clientAddress = clntSocket.getRemoteSocketAddress();
                System.out.println("Handling client at "+clientAddress);
                OutputStream out=clntSocket.getOutputStream();
                out.write("哈哈哈哈".getBytes());
                in = clntSocket.getInputStream();
                while((recvMsgSize=in.read(recvBuf))!=-1){
                    byte[] temp = new byte[recvMsgSize];
                    System.arraycopy(recvBuf, 0, temp, 0, recvMsgSize);
                    System.out.println("客户端发送："+new String(temp));
                }
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally{
            try{
                if(serverSocket!=null){
                    serverSocket.close();
                }
                if(in!=null){
                    in.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 使用nio的方式
     */
    public void start_server(){
        Selector selector=null;
        ServerSocketChannel channel=null;
        try {
            selector=Selector.open();
            channel=ServerSocketChannel.open();
            channel.socket().bind(new InetSocketAddress(9099));
            channel.configureBlocking(false);
            channel.register(selector,SelectionKey.OP_ACCEPT);
            //轮询 selector 查看selector的状态
            while (true){
                if(selector.select(1000)==0){
                    System.out.println("==");
                    continue;
                }
                Iterator<SelectionKey> itor=selector.selectedKeys().iterator();
                while (itor.hasNext()){
                    SelectionKey key=itor.next();
                    if(key.isAcceptable()){
                        handleAccept(key);
                    }else if(key.isReadable()){
                        hadleRead(key);
                    }else if (key.isWritable()){
                        handleWrite(key);
                    }else if(key.isConnectable()){
                        System.out.println("isconnectable==true");
                    }
                    itor.remove();
                }
            }
        }catch (Exception e){
                e.printStackTrace();
        }finally {

        }

    }

    public void handleWrite(SelectionKey key) throws IOException {
        ByteBuffer buf = (ByteBuffer)key.attachment();
        buf.clear();
        SocketChannel sc = (SocketChannel) key.channel();
        buf.put("哈哈哈哈".getBytes());
        buf.flip();
        sc.write(buf);

        sc.close();
    }

    /**
     * 设置可读
     * @param key
     * @throws IOException
     */
    public void handleAccept(SelectionKey key) throws IOException {
        ServerSocketChannel ssChannel = (ServerSocketChannel)key.channel();
        SocketChannel sc = ssChannel.accept();
        sc.configureBlocking(false);
        SelectionKey selectionKey=sc.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocateDirect(1024));
        //selectionKey.attach("attach .......................");
    }

    public void hadleRead(SelectionKey key) throws IOException {
        //Object obj=key.attachment();
       // System.out.println(obj);
        ByteBuffer buffer= (ByteBuffer) key.attachment();
        SocketChannel channel= (SocketChannel) key.channel();
        InetSocketAddress address= (InetSocketAddress) channel.getRemoteAddress();
        System.out.println(address.getHostName()+":"+address.getPort());
        int len=channel.read(buffer);

            buffer.flip();
            while (buffer.hasRemaining()){
                System.out.print((char)buffer.get());
            }
            buffer.compact();
            len=channel.read(buffer);
            System.out.println("wait");
            //Sets this key's interest set to the given value.
            key.interestOps(SelectionKey.OP_WRITE);


    }

    public static void main(String[] args) throws IOException {
        int processors=Runtime.getRuntime().availableProcessors();
        System.out.println("processors："+processors);
        Server server=new Server();
        server.start_server();


    }
}
